package com.woniuxy.kaer.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.kaer.commons.util.Data;
import com.woniuxy.kaer.commons.util.PageInfo;
import com.woniuxy.kaer.param.AddOrderParam;
import com.woniuxy.kaer.param.SearchOrderParam;
import com.woniuxy.kaer.redis.util.RedisKey;

import com.woniuxy.kaer.shop.config.WebSocketServer;
import com.woniuxy.kaer.shop.mapper.ProductMapper;
import com.woniuxy.kaer.shop.mapper.ProductOrderDataMapper;
import com.woniuxy.kaer.shop.model.Product;
import com.woniuxy.kaer.shop.model.ProductOrder;
import com.woniuxy.kaer.shop.mapper.ProductOrderMapper;
import com.woniuxy.kaer.shop.model.ProductOrderData;
import com.woniuxy.kaer.shop.service.ProductOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 郭建东
 * @since 2025年02月17日
 */
@Service
public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {

    @Resource
    private ProductOrderMapper productOrderMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private ProductOrderDataMapper productOrderDataMapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private AlipayClient alipayClient;

    @Value("${alipay.config.public-key}")
    private String publicKey;

    @Value("${alipay.callback.return-url}")
    private String returnUrl;

    @Value("${alipay.callback.notify-url}")
    private String notifyUrl;

    @Resource
    private ProductOrderService productOrderService;


    @Override
    public ProductOrder addOrder(AddOrderParam param, Integer userId) throws Exception {
        //1.对商品列表进行排序
        Arrays.sort(param.getProductIds());
        //2.循环创建锁 将锁组合为多资源锁（避免出现超卖情况）
        RLock[] lockList = new RLock[param.getProductIds().length];
        for (int i = 0; i < param.getProductIds().length; i++) {
            RLock fairLock = redissonClient.getFairLock(param.getProductIds()[i].toString());
            lockList[i] = fairLock;
        }
        RLock lock = redissonClient.getMultiLock(lockList);

        try {
            //3.加锁
            lock.lock();
            //4.判断商品是否存在于购物车中
            ArrayList<Map<Object, Object>> shopping = new ArrayList<Map<Object, Object>>();
            for (int i = 0; i < param.getProductIds().length; i++) {
                Double score = stringRedisTemplate.opsForZSet().score(RedisKey.userShoppingList(userId), param.getProductIds()[i].toString());
                if (score == null) {
                    throw new Exception("购物车不存在该商品");
                }else{
                    //将购物车的信息取出来存放到一个集合中
                    Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(RedisKey.userShoppingDetail(userId, param.getProductIds()[i]));
                    //取出排序值存放到map中 便于后续对redis做补偿
                    map.put("socre",score);
                    shopping.add(map);
                }
            }
            //5.判断库存量是否充足
            BigDecimal total = new BigDecimal("0");
            for (int i=0;i<shopping.size();i++){
                //取出购物车中的商品ID和购买数量
                int productId = Integer.parseInt(shopping.get(i).get("productId").toString());
                int number = Integer.parseInt(shopping.get(i).get("number").toString());
                //查询数据库中的商品信息
                Product product = productMapper.selectById(productId);
                //计算出该商品的小计
                BigDecimal m = new BigDecimal(number).multiply(product.getPrice());
                //累加到订单总金额
                total=total.add(m);
                //判断库存量是否充足
                if(product.getInventory()<number){
                    throw new Exception(product.getProductName()+"库存不足");
                }
            }

            //6.新增订单信息
            ProductOrder productOrder =  BeanUtil.toBean(param, ProductOrder.class);
            LocalDateTime now = LocalDateTime.now();
            productOrder.setOrderTime(now);
            //通过时间戳和用户ID生成订单ID
            String orderId = now.toString().replaceAll(":", "").replaceAll("-", "").replaceAll(" ", "").substring(0, 13);
            productOrder.setProductOrderId("U"+userId+"-"+orderId);
            productOrder.setTotal(total);
            productOrder.setUserId(userId);
            productOrder.setPayState(Data.ORDER_PAY_STATE_NOPAY);//订单状态 未支付
            productOrderMapper.insert(productOrder);
            //7.新增订单详情信息以及扣除库存以及删除购物车记录
            ArrayList<Map<Object,Object>> deleted=new ArrayList<Map<Object,Object>>();
            try{
                for(Map<Object,Object> map:shopping){
                    int productId = Integer.parseInt(map.get("productId").toString());
                    int number = Integer.parseInt(map.get("number").toString());
                    Product product = productMapper.selectById(productId);
                    ProductOrderData productOrderData = new ProductOrderData();
                    productOrderData.setProductId(productId);
                    productOrderData.setProductName(product.getProductName());
                    productOrderData.setProductNum(number);
                    productOrderData.setProductOrderId(productOrder.getProductOrderId());
                    productOrderData.setProductPrice(product.getPrice());
                    productOrderData.setProductPicture(product.getProductPicture());
                    productOrderDataMapper.insert(productOrderData);
                    //扣除库存
                    product.setInventory(product.getInventory()-number);
                    //修改冻结
                    product.setFreeze(product.getFreeze()+number);
                    //删除购物车记录
                    stringRedisTemplate.opsForZSet().remove(RedisKey.userShoppingList(userId),productId+"");
                    stringRedisTemplate.delete(RedisKey.userShoppingDetail(userId,productId));
                    //记录已经被删除的购物车记录
                    deleted.add(map);
                }
            }catch (Exception e){
                //通过补偿措施回滚redis中的购物车信息
                for (Map<Object, Object> map : deleted) {
                    String productId=map.get("productId").toString();
                    String number=map.get("number").toString();
                    stringRedisTemplate.opsForZSet().remove(RedisKey.userShoppingList(userId),productId);
                    stringRedisTemplate.delete(RedisKey.userShoppingDetail(userId,Integer.parseInt(productId)));
                }

                for(Map<Object,Object> map:deleted){
                    //新增数据Id到zest
                    String productId=map.get("productId").toString();
                    String number=map.get("number").toString();
                    double score = Double.parseDouble(map.get("score").toString());
                    stringRedisTemplate.opsForZSet().add(RedisKey.userShoppingList(userId),productId,(long)score);
                    //新增Hash
                    map.remove("score");
                    stringRedisTemplate.opsForHash().putAll(RedisKey.userShoppingDetail(userId,Integer.parseInt(productId)),map);
                }
                throw new Exception("订单支付失败");
            }
            //将订单编号加入到延迟队列 用于在一段时间之后检查订单的支付状态

            rabbitTemplate.convertAndSend("","confirm_order_pay_queue",productOrder.getProductOrderId());

            return productOrder;
        }finally {
            lock.unlock();
        }
    }

    @Override
    public String pay(String productOrderId, Integer userId) throws Exception {
        ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
        if(productOrder==null||!productOrder.getUserId().equals(userId)){
            throw new Exception("订单不存在");
        }
        //判断订单状态
        if(!productOrder.getPayState().equals(Data.ORDER_PAY_STATE_NOPAY)){
            throw new Exception("订单状态异常");
        }
//        //创建支付宝所需参数
//        HashMap<String, Object> params = new HashMap<>();
//        params.put("out_trade_no", productOrderId);
//        params.put("total_amount", productOrder.getTotal());
//        params.put("subject", "汽车商品购买订单");
//        params.put("body", "支付订单");
//        params.put("product_code", "FAST_INSTANT_TRADE_PAY");
//
//        ZoneId zoneId = ZoneId.systemDefault();
//        ZonedDateTime zonedDateTime = productOrder.getOrderTime().atZone(zoneId);
//        //获取时间戳，单位为毫秒
//        long time = zonedDateTime.toInstant().toEpochMilli();
//        Date date = new Date(time + 15 * 60 * 1000);
//        String expire = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
//        params.put("time_expire",expire);
//        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
//        //设置参数
//        request.setBizContent(JSONUtil.toJsonStr(params));
//
//
//        //发送请求
//        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
//        if(response.isSuccess()){
//            //返回支付宝响应的支付表单html内容
//            System.out.println("确认支付");
//            return response.getBody();
//        }
//        throw new Exception("发起支付失败");
        HashMap<String, String> params = new HashMap<>();
        params.put("trade_status", "TRADE_SUCCESS");
        params.put("out_trade_no", productOrderId);
        params.put("gmt_payment", LocalDateTime.now().toString().replace("T", " ").substring(0, 19));
        productOrderService.handleOrder(params);
        return null;
    }

    @Override
    @Transactional
    public void handleOrder(Map<String, String> params) throws Exception {
        System.out.println("公钥:"+publicKey);
        //验签
//        boolean b = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", "RSA2");
//        System.out.println("验签"+b);
//        if(b){
            //更新订单状态和商品的库存
            //获取订单编号和支付时间
            String productOrderId = params.get("out_trade_no");
            String tradeStatus = params.get("trade_status");
            if("TRADE_SUCCESS".equals(tradeStatus)){
                String payTime = params.get("gmt_payment");
                //更新订单的状态和商品的库存
                updateOrder(productOrderId, payTime);

                //给平台推送实时信息
                // 通知平台账户有新订单，假设平台账户的 userId 是 "platform"
                try {
                    String message = "订单 " + productOrderId + " 已支付，请及时处理发货。";
                    WebSocketServer.sendInfo(message, "1");
                } catch (IOException e) {
                    log.error("发送 WebSocket 消息失败: ", e);
                }
            }
//        }
    }
    //更新订单
    @Override
    @Transactional
    public void updateOrder(String productOrderId,String payTime) throws Exception {
        //查询订单信息
        ProductOrder productOrder = productOrderMapper.selectById(productOrderId);

        if(productOrder!=null){
            if(productOrder.getPayState()==Data.ORDER_PAY_STATE_NOPAY){
                //更新订单支付状态（待支付->已支付）
                productOrder.setPayState(Data.ORDER_PAY_STATE_PAYED);
                //更新订单状态（待发货）
                productOrder.setOrderState(Data.ORDER_STATE_WAITING);
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime date = LocalDateTime.parse(payTime, formatter);
                productOrder.setPayTime(date);
                System.out.println("支付时间"+date);
                productOrderMapper.updateById(productOrder);
                //查询订单详情
                QueryWrapper<ProductOrderData> queryWrapper= new QueryWrapper<>();
                queryWrapper.eq("product_order_id", productOrderId);
                List<ProductOrderData> productOrderDatas = productOrderDataMapper.selectList(queryWrapper);
                for (ProductOrderData productOrderData : productOrderDatas) {
                    //使用分布式锁加锁
                    RLock lock = redissonClient.getFairLock(RedisKey.LOCK_PRODUCTID(productOrderData.getProductId()));
                    try{
                        lock.lock();
                        Product product = productMapper.selectById(productOrderData.getProductId());
                        product.setFreeze(product.getFreeze()-productOrderData.getProductNum());
                        productMapper.updateById(product);
                    }finally {
                        lock.unlock();
                    }
                }
            }
        }
    }

    //取消订单
    @Override
    public void cancelOrder(String productOrderId) throws Exception {
        ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
        if(productOrder!=null){
            //订单状态未支付
            if (productOrder.getPayState().equals(Data.ORDER_PAY_STATE_NOPAY)) {
                //订单支付超时
                //修改订单状态为支付取消
                productOrder.setPayState(Data.ORDER_PAY_CANCEL);
                productOrderMapper.updateById(productOrder);
                //查询订单详情
                QueryWrapper<ProductOrderData> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("product_order_id", productOrderId);
                List<ProductOrderData> productOrderDatas = productOrderDataMapper.selectList(queryWrapper);
                //查询订单详情，恢复库存，减少冻结量
                for (ProductOrderData productOrderData : productOrderDatas){
                    QueryWrapper<Product> wrapper = new QueryWrapper<>();
                    wrapper.eq("product_id",productOrderData.getProductId());
                    Product product = productMapper.selectOne(wrapper);
                    if(product==null){
                        throw new Exception("商品不存在");
                    }
                    //恢复库存，减少冻结量
                    product.setFreeze(product.getFreeze()-productOrderData.getProductNum());
                    product.setInventory(product.getInventory()+productOrderData.getProductNum());
                    productMapper.updateById(product);
                }
            }
        }
    }

    @Override
    public void confirmOrder(String productOrderId, Integer userId) {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_order_id",productOrderId);
        ProductOrder productOrder = productOrderMapper.selectOne(queryWrapper);
        if(productOrder==null){
            throw new RuntimeException("订单信息不存在");
        }
        //订单状态不为已发货时不可以确认收货
        if(!productOrder.getOrderState().equals(Data.ORDER_STATE_SEND)){
            throw new RuntimeException("订单状态异常");
        }
        //修改订单状态为待评价
        productOrder.setOrderState(Data.ORDER_STATE_EVALUATE);
        productOrderMapper.updateById(productOrder);
        //将订单编号加入到延迟队列 用于在一段时间之后检查订单是否评价

        rabbitTemplate.convertAndSend("","evaluate_order_queue",productOrder.getProductOrderId());

    }

    @Override
    public void shipments(String productOrderId) throws Exception {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_order_id",productOrderId);
        ProductOrder productOrder = productOrderMapper.selectOne(queryWrapper);
        if(productOrder==null){
            throw new Exception("订单信息不存在");
        }
        if(productOrder.getOrderState()!=Data.ORDER_STATE_WAITING&&productOrder.getPayState()!=Data.ORDER_PAY_STATE_PAYED){
            throw new Exception("订单状态异常");
        }
        productOrder.setOrderState(Data.ORDER_STATE_SEND);
        productOrderMapper.updateById(productOrder);
//        String message = "订单 " + productOrderId + " 已发货,请注意查收。";
//        WebSocketServer.sendInfo(message, "1");
    }

//    @Override
//    public PageInfo searchOrder(SearchOrderParam param) throws Exception {
//        if(param.getPageNum()==null || param.getPageNum()==0){
//            throw new Exception("页码不能为0");
//        }
//        if(param.getPageSize()==null || param.getPageSize()==0){
//            throw new Exception("页大小不能为0");
//        }
//        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
//        if(param.getOrderState()!=-1){
//            queryWrapper.eq("order_state",param.getOrderState());
//        }
//        Page<ProductOrder> productOrderPage = productOrderMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), queryWrapper);
//        PageInfo productOrderPageInfo = new PageInfo(productOrderPage);
//        return productOrderPageInfo;
//
//    }
//
//    @Override
//    public PageInfo searchMyOrder(SearchOrderParam param, Integer userId) throws Exception {
//        if(param.getPageNum()==null || param.getPageNum()==0){
//            throw new Exception("页码不能为0");
//        }
//        if(param.getPageSize()==null || param.getPageSize()==0){
//            throw new Exception("页大小不能为0");
//        }
//        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
//        if(param.getOrderState()!=-1){
//            queryWrapper.eq("order_state",param.getOrderState())
//                    .eq("user_id",userId);
//        }
//        Page<ProductOrder> productOrderPage = productOrderMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), queryWrapper);
//        PageInfo productOrderPageInfo = new PageInfo(productOrderPage);
//        return productOrderPageInfo;
//    }

    @Override
    public PageInfo searchOrders(SearchOrderParam param, Integer userId) throws Exception {
        if(param.getPageNum()==null || param.getPageNum()==0){
            throw new Exception("页码不能为0");
        }
        if(param.getPageSize()==null || param.getPageSize()==0){
            throw new Exception("页大小不能为0");
        }
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        if(param.getOrderState()!=-1){
            queryWrapper.eq("order_state",param.getOrderState());
        }
        if(userId!=null){
            queryWrapper.eq("user_id",userId);
        }
        queryWrapper.eq("pay_state",1);
        Page<ProductOrder> productOrderPage = productOrderMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), queryWrapper);
        PageInfo productOrderPageInfo = new PageInfo(productOrderPage);
        return productOrderPageInfo;
    }
}
